import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Deck, Card, ReviewRating } from './types';

interface DeckContextType {
  decks: Deck[];
  addDeck: (name: string, description?: string) => void;
  deleteDeck: (deckId: string) => void;
  addCard: (deckId: string, front: string, back: string) => void;
  deleteCard: (deckId: string, cardId: string) => void;
  reviewCard: (deckId: string, cardId: string, rating: ReviewRating) => void;
  getDueCards: (deckId: string) => Card[];
  loading: boolean;
}

const DeckContext = createContext<DeckContextType | undefined>(undefined);

const STORAGE_KEY = '@tigerdeck:decks';

// SM-2算法计算下次复习时间
const calculateNextReview = (card: Card, rating: ReviewRating): Partial<Card> => {
  let { ease, interval, repetitions } = card;

  if (rating === ReviewRating.Again) {
    // 重新开始
    repetitions = 0;
    interval = 1;
  } else {
    if (repetitions === 0) {
      interval = 1;
    } else if (repetitions === 1) {
      interval = 6;
    } else {
      interval = Math.round(interval * ease);
    }

    repetitions += 1;

    // 调整难度系数
    ease = ease + (0.1 - (5 - rating) * (0.08 + (5 - rating) * 0.02));
    if (ease < 1.3) ease = 1.3;
  }

  const nextReviewDate = new Date();
  nextReviewDate.setDate(nextReviewDate.getDate() + interval);

  return {
    ease,
    interval,
    repetitions,
    nextReviewDate,
    lastReviewed: new Date(),
  };
};

export const DeckProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [decks, setDecks] = useState<Deck[]>([]);
  const [loading, setLoading] = useState(true);

  // 加载数据
  useEffect(() => {
    loadDecks();
  }, []);

  // 保存数据
  useEffect(() => {
    if (!loading) {
      saveDecks();
    }
  }, [decks, loading]);

  const loadDecks = async () => {
    try {
      const data = await AsyncStorage.getItem(STORAGE_KEY);
      if (data) {
        const parsedDecks = JSON.parse(data);
        // 转换日期字符串为Date对象
        const decksWithDates = parsedDecks.map((deck: any) => ({
          ...deck,
          createdAt: new Date(deck.createdAt),
          updatedAt: new Date(deck.updatedAt),
          cards: deck.cards.map((card: any) => ({
            ...card,
            nextReviewDate: card.nextReviewDate ? new Date(card.nextReviewDate) : undefined,
            lastReviewed: card.lastReviewed ? new Date(card.lastReviewed) : undefined,
          })),
        }));
        setDecks(decksWithDates);
      }
    } catch (error) {
      console.error('Failed to load decks:', error);
    } finally {
      setLoading(false);
    }
  };

  const saveDecks = async () => {
    try {
      await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(decks));
    } catch (error) {
      console.error('Failed to save decks:', error);
    }
  };

  const addDeck = (name: string, description?: string) => {
    const newDeck: Deck = {
      id: Date.now().toString(),
      name,
      description,
      cards: [],
      createdAt: new Date(),
      updatedAt: new Date(),
    };
    setDecks([...decks, newDeck]);
  };

  const deleteDeck = (deckId: string) => {
    setDecks(decks.filter(deck => deck.id !== deckId));
  };

  const addCard = (deckId: string, front: string, back: string) => {
    const newCard: Card = {
      id: Date.now().toString(),
      front,
      back,
      deckId,
      ease: 2.5,
      interval: 0,
      repetitions: 0,
    };

    setDecks(
      decks.map(deck =>
        deck.id === deckId
          ? { ...deck, cards: [...deck.cards, newCard], updatedAt: new Date() }
          : deck
      )
    );
  };

  const deleteCard = (deckId: string, cardId: string) => {
    setDecks(
      decks.map(deck =>
        deck.id === deckId
          ? {
              ...deck,
              cards: deck.cards.filter(card => card.id !== cardId),
              updatedAt: new Date(),
            }
          : deck
      )
    );
  };

  const reviewCard = (deckId: string, cardId: string, rating: ReviewRating) => {
    setDecks(
      decks.map(deck =>
        deck.id === deckId
          ? {
              ...deck,
              cards: deck.cards.map(card =>
                card.id === cardId
                  ? { ...card, ...calculateNextReview(card, rating) }
                  : card
              ),
              updatedAt: new Date(),
            }
          : deck
      )
    );
  };

  const getDueCards = (deckId: string): Card[] => {
    const deck = decks.find(d => d.id === deckId);
    if (!deck) return [];

    const now = new Date();
    return deck.cards.filter(
      card => !card.nextReviewDate || card.nextReviewDate <= now
    );
  };

  return (
    <DeckContext.Provider
      value={{
        decks,
        addDeck,
        deleteDeck,
        addCard,
        deleteCard,
        reviewCard,
        getDueCards,
        loading,
      }}
    >
      {children}
    </DeckContext.Provider>
  );
};

export const useDeck = () => {
  const context = useContext(DeckContext);
  if (context === undefined) {
    throw new Error('useDeck must be used within a DeckProvider');
  }
  return context;
};
